package com.hsmpay.mobile.service.user.impl;

import com.hsmpay.common.pojo.user.Person;
import com.hsmpay.common.pojo.user.User;
import com.hsmpay.common.service.impl.MemcachedServiceSupport;
import com.hsmpay.common.util.ClearMac;
import com.hsmpay.common.util.DateConvertUtil;
import com.hsmpay.common.util.NumberUtil;
import com.hsmpay.common.util.memcached.UserModel;
import com.hsmpay.mobile.dao.trans.CombineOrderDao;
import com.hsmpay.mobile.dao.trans.TransOrderDao;
import com.hsmpay.mobile.dao.user.*;
import com.hsmpay.mobile.pojo.trans.CombineOrder;
import com.hsmpay.mobile.pojo.trans.TransOrder;
import com.hsmpay.mobile.pojo.user.*;
import com.hsmpay.mobile.service.user.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 用户业务接口实现类 userService
 * 对应数据层 userDao
 *
 * @author 颜铃璋
 * @date 2012-12-14
 */
@Service("userService")
public class UserServiceImpl extends MemcachedServiceSupport<User, Long> implements UserService<User, Long> {
    @Resource(name = "userDao")
    private UserDao<User, Long> userDao;//用户dao
    @Resource(name = "activationHistoryDao")
    private ActivationHistoryDao<ActivationHistory, Long> activationHistoryDao;//激活历史记录dao
    @Resource(name = "personDao")
    private PersonDao<Person, Long> personDao;//用户详情dao
    @Resource(name = "userMoneyDao")
    UserMoneyDao<UserMoney, Long> userMoneyDao;//用户虚拟货币dao
    @Resource(name = "activationCodeDao")
    private ActivationCodeDao<ActivationCode, Long> activationCodeDao;
    @Resource(name = "bindingBankCardLogDao")
    private BindingBankCardLogDao<BindingBankCardLog, Long> bindingBankCardLogDao;//绑定银行卡
    @Resource(name = "transOrderDao")
    private TransOrderDao<TransOrder, Long> transOrderDao;
    //	@Resource(name="transPriorSettleDao")
//	private TransPriorSettleDao<TransPriorSettle, Long> transPriorSettleDao;
    @Resource(name = "combineOrderDao")
    private CombineOrderDao<CombineOrder, Long> combineOrderDao;

    @Resource(name = "userTransLimitDao")
    private UserTransLimitDao<UserTransLimit, Long> userTransLimitDao;


    public UserModel findById(Long id) throws Exception {
        Object entity = getCacheData(new StringBuilder(WANJX_USER_INFO_DETAIL_KEY).append(id).toString());
        if (entity != null) {
            return (UserModel) entity;
        } else {
            return null;
        }
    }

    public boolean setCacheEntity(UserModel entity) throws Exception {
        return setCacheData(new StringBuilder(WANJX_USER_INFO_DETAIL_KEY).append(entity.getUser().getId()).toString(), entity);
    }

    /**
     * 根据主键ID memcached 保存的用户 model
     *
     * @return
     * @throws Exception
     */
    public UserModel getUserModelById(Long userId) throws Exception {
        UserModel userModel = findById(userId);
        if (null == userModel) {
            userModel = flushUserModelById(userId);
        }
        return userModel;
    }

    //重新到数据库里面去查询
    private UserModel flushUserModelById(Long userId) throws Exception {
        UserModel userModel = new UserModel();
        User user = new User();
        user.setDeleted(0);
        user.setId(userId);
        user = userDao.searchEntity(user);
        if (null != user) {
            userModel.setUser(user);
            return userModel;
        }
        return null;
    }

    /**
     * 根据注册码注册用户
     *
     * @param user
     * @return
     * @throws Exception
     */
    public Long register(User user, ActivationHistory activationHistory) throws Exception {
        Long userId = userDao.insertEntity(user);
        //添加person
        Person person = new Person();
        person.setUserId(userId);
        person.setMobile(user.getMobile());
        person.setUserName(user.getUserName());
        person.setBusinessRangeId(user.getBusinessRangeId());
        person.setBusinessAddress(user.getBusinessAddress());
        person.setDPIStatus(3);
        personDao.insertEntity(person);
        //激活码 注册历史记录
        if (null != activationHistory) {
            activationHistory.setUserId(userId);
            activationHistoryDao.insertEntity(activationHistory);

            //修改激活码表 为已被注册
            ActivationCode activationCode = new ActivationCode();
            activationCode.setId(activationHistory.getCodeId());
            long codeId = activationHistory.getCodeId();
            activationCode.setIsActivation(1);
            if (codeId != 1 && codeId != 2) {//屏蔽ABCD 不修改ABCD
                activationCodeDao.updateEntity(activationCode);
            }
        }

        //添加对应的用户限制
        for (int i = 0; i < 2; i++) {
            UserTransLimit utl = new UserTransLimit();
            if (i == 0) utl.setFunctionKey("RECEIVABLES");//收款
            if (i == 1) utl.setFunctionKey("CARD2CARDTRANSFER");//卡卡转账
            utl.setLimitType(1);//默认限制
            utl = userTransLimitDao.searchEntity(utl);

            utl.setId(null);
            utl.setUserId(userId);
            utl.setLimitType(2);//用户限制
            userTransLimitDao.insertEntity(utl);
        }


        //添加对应的
        UserMoney userMoney = new UserMoney();
        userMoney.setUserId(user.getId());
        userMoney.setMoney(0.0);
        userMoney.setFreezeMoney(0.0);
        userMoney.setAvailMoney(0.0);
        userMoneyDao.insertEntity(userMoney);

        //保存用户到 memcache
        UserModel userModel = new UserModel();
        userModel.setUser(user);
        setCacheEntity(userModel);

        //下单 并 添加绑定历史记录
        //bindingBankCardOrder(user,user.getBankStatus());

        return userId;
    }

    /**
     * 根据userId 获得user
     *
     * @param userId
     * @return
     * @throws Exception
     */
    public User getUserById(Long userId) throws Exception {
        UserModel userModel = getUserModelById(userId);
        return userModel.getUser();
    }

    /**
     * 绑定银行卡
     *
     * @param user
     * @return
     * @throws Exception
     */
    public int bindingBankCard(User user) throws Exception {
        UserModel userModel = getUserModelById(user.getId());

        //修改用户详细信息 真实姓名
        Person persen = new Person();
        persen.setUserId(user.getId());
        persen = personDao.searchEntity(persen);
        persen.setUserName(user.getUserName());//修改用户姓名
        personDao.updateEntity(persen);

        //修改用户对象  绑定银行卡 身份证 开户行
        user.setBankStatus(1);//现在需求改了 只要修改银行卡  就默认银行卡是通的 //将绑定银行状态修改为正在处理中
        int flag = userDao.updateEntity(user);

        //修改memache中的用户信息
        userModel.setUser(user);
        setCacheEntity(userModel);

        //将该用户 结算失败的订单改为等待结算
        CombineOrder combineOrder = new CombineOrder();
        combineOrder.setLoginName(user.getLoginName());
        combineOrder.setTerminalTypeId(user.getTerminalTypeId());
        combineOrder.setStatus(0);//结算失败的
        combineOrder.setIsReturnAB(0);//未回滚
        combineOrder.setClearType(2);//结算才允许修改合单信息

        List<CombineOrder> combineOrderList = combineOrderDao.searchEntityList(combineOrder);
        for (int i = 0; i < combineOrderList.size(); i++) {
            CombineOrder co = combineOrderList.get(i);
            co.setStatus(3);//等待结算
            co.setReClear(1);
            co.setBankCard(user.getBankCard());
            co.setOpeningBank(user.getOpeningBank());
            co.setBranchesBank(user.getBranchesBank());
            co.setBBankProvince(user.getBBankProvince());
            co.setBBankCity(user.getBBankCity());
            co.setBranchesBankCode(user.getBranchesBankCode());
            co.setAccBankCode(user.getAccBankCode());
            String clearMac = ClearMac.getCoClearMac(co.getLoginName(), co.getTransMoney(), co.getBankCard(), co.getOpeningBank(), co.getUserName(), co.getBatchCoId());
            co.setClearMac(clearMac);

            combineOrderDao.updateEntity(co);//修改结算信息
        }


        //下单 并 添加绑定历史记录
        bindingBankCardOrder(user, user.getBankStatus());
        return flag;
    }

    /**
     * 暂时没有用了  现在绑定银行卡默认是通过的  只要交易一遍失败了
     *
     * @param user
     * @throws Exception
     */
    @SuppressWarnings("unused")
    private void bindingBankCardOrder(User user, Integer bankStatus) throws Exception {
        //添加 （添加/修改）绑定银行卡历史记录
        BindingBankCardLog bbcl = new BindingBankCardLog();
        bbcl.setUserId(user.getId());
        bbcl.setBankCard(user.getBankCard());
        bbcl.setOpeningBank(user.getOpeningBank());
        bbcl.setBranchesBank(user.getBranchesBank());
        bbcl.setBBankProvince(user.getBBankProvince());
        bbcl.setBBankCity(user.getBBankCity());
        bbcl.setCardholder(user.getCardholder());
        bbcl.setBranchesBankCode(user.getBranchesBankCode());
        bbcl.setStatus(bankStatus);
        bindingBankCardLogDao.insertEntity(bbcl);

        transOrderDao.updateUnCOrderClearing(user);
        /*//添加 一分钱订单
		Date date = new Date();
		TransOrder transOrder = new TransOrder();
		transOrder.setOrderNum(getOrderNumByDate(date,user.getId()));
		transOrder.setOrderTypeId(OrderTypeUtil.BINDING_BANK_CARD);//绑定银行卡
		transOrder.setUserId(user.getId());
		transOrder.setPUserId(user.getPUserId());//父用户Id
		transOrder.setTransMoney(0.01);
		transOrder.setFeeMoney(0.00);//手续费
		transOrder.setChargeAmount(0.01);
		transOrder.setRootCategory("绑定银行卡");
		transOrder.setCategory("测试银行卡");
		//transOrder.setName(user.getCardholder());//user.getUserName());//付款方
		//transOrder.setBankCard(user.getBankCard());
		//transOrder.setOpeningBank(user.getOpeningBank());//"农业银行");//);
		transOrder.setObjectiveName(user.getCardholder());//对方姓名
		transOrder.setObjectiveCard(user.getBankCard());//对方银行卡
		transOrder.setObjectiveOpBank(user.getOpeningBank());//对方银行
		transOrder.setStatus(2);//交易状态  0交易失败 1交易成功 2银行交易处理中 3 未付款 4等待对方付款5关闭交易
		transOrder.setClearing(0);//结算状态 0未结算 1结算
		transOrder.setDescription("");//交易详情
		transOrder.setCreateDate(date);
		transOrder.setUpdateLongTime(date.getTime());
		
		//transOrder.setBranchesBank(user.getBranchesBank());//用户银行支行
		//transOrder.setBBankProvince(user.getBBankProvince());
		//transOrder.setBBankCity(user.getBBankCity());
		//transOrder.setMobile(user.getMobile());//用户 手机号
		transOrder.setObjectiveBBank(user.getBranchesBank());//对方。银行支行
		transOrder.setObjectiveBBProvince(user.getBBankProvince());
		transOrder.setObjectiveBBCity(user.getBBankCity());
		transOrder.setObjectiveMobile(user.getMobile());//对方手机号
		//log.debug("##---------------"+user.getBranchesBankCode());
		transOrder.setObjectiveBBankCode(user.getBranchesBankCode());//支行号
		//transOrder.setX(x);//经度
		//transOrder.setY(y);//维度	
		transOrder.setBrokerage(0.000);
		transOrder.setDealerBrokerage(0.000);
		transOrderDao.insertEntity(transOrder);
		
		//添加订单收款
		TransPriorSettle transPriorSettle = new TransPriorSettle();
		transPriorSettle.setOrderNum(transOrder.getOrderNum());
		transPriorSettle.setStatus(1);
		transPriorSettle.setCollectionType(0);//0 为账户余额 1 为银联接口 2 为代收2元一笔的实时代收
		transPriorSettleDao.insertEntity(transPriorSettle);*/
    }


    /**
     * 获得订单编号
     *
     * @param date
     * @return
     */
    protected String getOrderNumByDate(Date date, Long userId) {
        StringBuilder sb = new StringBuilder();
        String dt = DateConvertUtil.dateString(date, "yyyyMMddHHmmss");//获得日期字符串
        String userIdStr = NumberUtil.supplyAll(userId, 10);//获得10位userId
        long r = (long) (Math.random() * 10000);//获得四位随机数
        String rStr = NumberUtil.supplyAll(r, 4);
        return sb.append(dt).append(userIdStr).append(rStr).toString();
    }

    /**
     * 用户注销
     *
     * @param userId
     * @return
     * @throws Exception
     */
    public boolean userLogout(Long userId) throws Exception {
        return removeCacheNode(new StringBuilder(WANJX_USER_INFO_DETAIL_KEY).append(userId).toString());
    }

    /**
     * 修改密码
     *
     * @param user
     * @return
     * @throws Exception
     */
    public boolean updateUserPasseword(User user) throws Exception {
        //修改用户密码
        updateEntity(user);
        //修改memache中的用户密码
        UserModel userModel = getUserModelById(user.getId());
        userModel.setUser(user);
        return setCacheEntity(userModel);
    }

    /**
     * 更改产品类型（前端角色）
     *
     * @param user
     * @param activationHistory
     * @return
     * @throws Exception
     */
    public boolean updateAppRole(User user, ActivationHistory activationHistory) throws Exception {
        //修改产品类型（前端角色）
        updateEntity(user);
        //激活码 注册历史记录
        if (null != activationHistory) {
            activationHistoryDao.insertEntity(activationHistory);
        }
        //修改memache中的用户
        UserModel userModel = getUserModelById(user.getId());
        userModel.setUser(user);
        return setCacheEntity(userModel);
    }

    /**
     * 更新Info_Person表中的实名认证状态
     *
     * @param person
     * @param user
     * @return
     * @throws Exception
     */
    public int updateDPIStatus(Person person, User user) throws Exception {
        //这里只修改 用户实名认证状态  其他的数据等认证成功了 认证的时候才可以修改 ######
//		UserModel userModel = getUserModelById(user.getId());
//		//修改memache中的用户信息 
//		userModel.setUser(user);
//		setCacheEntity(userModel);
//		
//		//重新算 Mac
//		String clearMac = ClearMac.getUserClearMac(user.getLoginName(),user.getIdentityCard(),user.getBankCard(), user.getOpeningBank(), user.getCardholder());
//		user.setClearMac(clearMac);
//		userDao.updateEntity(user);
        return personDao.updateDPIStatus(person);
    }


    /**
     * 保存用户 到 Memcached
     *
     * @param user
     * @return
     * @throws Exception
     */
    public boolean saveMemcachedByUser(User user) throws Exception {
        boolean flag = false;
        String key = new StringBuilder(WANJX_USER_INFO_DETAIL_KEY).append(user.getId()).toString();
        UserModel oMUserModel = (UserModel) getUserModelById(user.getId());

        UserModel userModel = new UserModel();
        userModel.setUser(user);
        if (null == oMUserModel) {//如果 不存在  就添加
            flag = setCacheData(key, userModel);
        } else {//如果  存在  替换
            flag = cas(key, userModel);
        }
        return flag;
    }

    /**
     * 根据 用户ID 从Memcached中取出用户   然后 根据登录时间 判断登录先后
     *
     * @param user
     * @return
     */
    public boolean isOldMemcachedUser(User user) throws Exception {
        UserModel oMUserModel = (UserModel) findById(user.getId());
        if (null == oMUserModel) {//直接保存
//			oMUserModel = new UserModel();
//			if(null != user){
//				oMUserModel.setUser(user);
//				setCacheEntity(oMUserModel);//保存用户到memcache
//			}
            oMUserModel = flushUserModelById(user.getUserId());
            if (null != oMUserModel) {
                oMUserModel.getUser().createDate = user.createDate;
            }
            return false;
        }
        Date createDate = user.createDate;
        if (null != oMUserModel && null != oMUserModel.getUser() && createDate.before(oMUserModel.getUser().createDate)) {
            return true;
        }
        return false;
    }

    /**
     * 根据登录名  查询用户
     *
     * @param loginName
     * @return
     * @throws Exception
     */
    public User searchUserByLoginName(String loginName) throws Exception {
        User user = new User();
        user.setLoginName(loginName);
        return userDao.searchEntity(user);
    }

    /**
     * 绑定刷卡器
     *
     * @param user
     * @return
     * @throws Exception
     */
    public int bindingMachine(User user) throws Exception {
        return updateUser(user);
    }

    /**
     * 修改 提现类型   为了以后扩展  不跟 绑定刷卡器
     *
     * @param user
     * @return
     * @throws Exception
     */
    public int updateCrashT1Type(User user) throws Exception {
        return updateUser(user);
    }

    /**
     * 修改 用户  更新数据库  更新memcached
     *
     * @param user
     * @return
     * @throws Exception
     */
    public int updateUser(User user) throws Exception {
        int flag = userDao.updateEntity(user);

        UserModel userModel = getUserModelById(user.getId());
        //修改memache中的用户信息
        userModel.setUser(user);
        setCacheEntity(userModel);

        return flag;
    }

    /**
     * 修改用户 为暂停结算 用户
     *
     * @param userId
     * @param description
     * @return
     * @throws Exception
     */
    public int updateRefuseClearStatus(Long userId, String description) throws Exception {
        //修改用户表
        User userParam = new User();
        userParam.setId(userId);
        userParam.setClearStatus(2);//暂停
        userParam.setDescription(description);
        int flag = userDao.updateEntity(userParam);

        //修改 memache中的用户信息
        UserModel userModel = findById(userId);
        if (null != userModel) {//如果 memache 中存在  那么修改
            User user = userModel.getUser();
            user.setClearStatus(userParam.getClearStatus());
            setCacheEntity(userModel);
        }

        return flag;
    }

    /**
     * 修改用户  通道
     *
     * @param reqCode
     * @param userId
     * @return
     * @throws Exception
     */
    public int updateUserChannelId(String reqCode, Long userId) throws Exception {
        int flag = 1;
        if ("6L".equals(reqCode) || "TR".equals(reqCode)) {//终端号解析失败  同卡当日跨商户交易
            //修改用户表
            User userParam = new User();
            userParam.setId(userId);
            userParam.setChannelId(32L);//切到卡莱
            flag = userDao.updateEntity(userParam);

            UserModel userModel = findById(userId);
            if (null != userModel) {//如果 memache 中存在  那么修改
                User user = userModel.getUser();
                user.setChannelId(userParam.getChannelId());
                setCacheEntity(userModel);
            }
        }
        return flag;
    }

    //---------------------set get start--------------------
    //---------------------set get end----------------------
}
